package com.example.wuqiu.config.tcp;

import com.example.wuqiu.module.sys.service.SysWebsocketService;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.util.CharsetUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author AmielTian
 */
@Component
@Slf4j
public class NettyTcpServer {

    @Resource
    private SysWebsocketService websocketService;
    // 监听端口
    @Value("${server.port:2200}")
    private int port;
    private final Map<String, ChannelHandlerContext> clientChannels = new ConcurrentHashMap<>();

    // 设置为你需要的最大帧长度（比如 10MB）
    int maxFrameLength = 10 * 1024 * 1024;
    int lengthFieldOffset = 1;
    // 长度字段的长度，假设长度字段占 4 字节
    int lengthFieldLength = 4;
    int lengthAdjustment = 0;
    int initialBytesToStrip = 0;
    @PostConstruct
    public void start() {
        port = port + 1;
        new Thread(() -> {
            EventLoopGroup bossGroup = new NioEventLoopGroup();
            EventLoopGroup workerGroup = new NioEventLoopGroup();

            try {
                ServerBootstrap bootstrap = new ServerBootstrap();
                bootstrap.group(bossGroup, workerGroup)
                        .channel(NioServerSocketChannel.class)
                        .childHandler(new ChannelInitializer<SocketChannel>() {
                            @Override
                            protected void initChannel(SocketChannel ch) {
                                ChannelPipeline pipeline = ch.pipeline();
                                // 解决粘包/拆包问题
                                //pipeline.addLast(new LengthFieldBasedFrameDecoder(maxFrameLength, lengthFieldOffset, lengthFieldLength, lengthAdjustment, initialBytesToStrip));
                                // 使用 4 字节的长度字段
                                //pipeline.addLast(new LengthFieldPrepender(lengthFieldLength));
                                // 如果需要处理字符串消息，可以保留 StringDecoder 和 StringEncoder
                                pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));
                                pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8));
                                // 自定义的消息处理器
                                pipeline.addLast(new TcpServerHandler(clientChannels, websocketService));

                            }
                        })
                        // 设置 TCP 的 backlog
                        .option(ChannelOption.SO_BACKLOG, 128)
                        // 开启 TCP Keep-Alive
                        .childOption(ChannelOption.SO_KEEPALIVE, true);

                ChannelFuture future = bootstrap.bind(port).sync();
                log.info("Netty TCP Server started on port: " + port);
                // 等待服务器通道关闭
                future.channel().closeFuture().sync();
            } catch (InterruptedException e) {
                log.error("Server interrupted: ", e);
                e.printStackTrace();
            } finally {
                bossGroup.shutdownGracefully();
                workerGroup.shutdownGracefully();
                log.info("Netty server shut down gracefully.");
            }
        }).start();
    }
}